﻿using StackExchange.Redis;
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

namespace Redis.Library
{
    /// <summary>
    /// 对RedisConnectPool的管理
    /// </summary>
    internal class RedisConnectPoolManager
    {

        //存储已存在链接
        private static readonly ConcurrentDictionary<string, RedisConnectPool> ConnectorCollection =
            new ConcurrentDictionary<string, RedisConnectPool>();



        /// <summary>
        /// 初始化链接池
        /// </summary>
        /// <param name="sectionName"></param>
        /// <param name="connectionStr"></param>
        /// <param name="poolSize"></param>
        internal static void Create(string sectionName, string connectionStr, int poolSize = 1)
        {
            if (ConnectorCollection.ContainsKey(sectionName))
                return;

            AddOrUpdate(sectionName, connectionStr, poolSize);
        }

        /// <summary>
        /// 添加/更新连接池
        /// </summary>
        /// <param name="sectionName"></param>
        /// <param name="connectionStr"></param>
        /// <param name="poolSize"></param>
        internal static void AddOrUpdate(string sectionName, string connectionStr, int poolSize = 1)
        {
            Func<RedisConnectPool> addPoolFunc = () => { return new RedisConnectPool(connectionStr, poolSize); };

            ConnectorCollection.AddOrUpdate(sectionName, key => addPoolFunc(), (x, oldPool) =>
            {
                // 延迟100秒卸载,避免卸载太快造成无法使用问题
                new Task(() =>
                {
                    Thread.Sleep(100000);
                    oldPool.Dispose();
                }).Start();

                return addPoolFunc();
            });
        }

        /// <summary>
        /// 连接池是否存在
        /// </summary>
        /// <param name="sectionName"></param>
        /// <returns></returns>
        public static bool Exists(string sectionName)
        {
            return ConnectorCollection.ContainsKey(sectionName);
        }

        /// <summary>
        /// 从池中取出一个连接
        /// 检查连接是否断开
        /// </summary>
        /// <param name="sectionName"></param>
        /// <returns></returns>
        public static ConnectionMultiplexer GetConnectionMultiplexer(string sectionName)
        {
            var pool = GetPool(sectionName);
            return pool.GetConnection();
        }

        /// <summary>
        /// 获取特定section的connectionPool
        /// </summary>
        /// <param name="sectionName"></param>
        /// <returns></returns>
        public static RedisConnectPool GetPool(string sectionName)
        {
            RedisConnectPool pool = null;
            if (!ConnectorCollection.TryGetValue(sectionName, out pool))
                throw new Exception(string.Format("Redis Section [{0}] 没有被初始化", sectionName));

            return pool;
        }
    }
}
